package com.zt.ztyh.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zt.ztyh.config.IdWorker;
import com.zt.ztyh.entity.ZtyhRecording;
import com.zt.ztyh.exception.ZhentaoException;
import com.zt.ztyh.pojo.UserByInfo;
import com.zt.ztyh.pojo.UserVo;
import com.zt.ztyh.service.UserService;
import com.zt.ztyh.service.ZtyhCardOpen;
import com.zt.ztyh.service.ZtyhRecordingserviceOpen;
import com.zt.ztyh.vo.UserInfoVo;
import com.zt.ztyh.vo.ValidateCodeVo;
import com.zt.ztyh.dto.UserDto;
import com.zt.ztyh.pojo.User;
import com.zt.ztyh.dto.LoginDto;
import com.zt.ztyh.vo.LoginVo;
import com.zt.ztyh.mapper.UserMapper;
import com.zt.ztyh.vo.common.Result;
import com.zt.ztyh.vo.common.ResultCodeEnum;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
* @author 卫相阳
* @description 针对表【ztyh_user】的数据库操作Service实现
* @createDate 2024-04-02 18:47:30
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ZtyhRecordingserviceOpen ztyhRecordingserviceOpen;
    @Autowired
    private ZtyhCardOpen ztyhCardOpen;
    @Override
    public LoginVo login(LoginDto loginDto) {
        //数据校验
        if (ObjectUtil.isEmpty(loginDto)) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        if (StrUtil.isBlank(loginDto.getCaptcha())) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        String vadlicode = redisTemplate.opsForValue().get("validateCode:" + loginDto.getCodeKey());
        if (StrUtil.isBlank(vadlicode)) {
            throw new com.zt.ztyh.exception.ZhentaoException(ResultCodeEnum.CAPTCHA_ERROR);
        }
        if (!vadlicode.equalsIgnoreCase(loginDto.getCaptcha())) {
            throw new ZhentaoException(ResultCodeEnum.VALIDATECODE_ERROR);
        }
        //用户输入的密码
        String password = loginDto.getPassword();
        //根据用户名进行查询
        User login = userMapper.selectOne(new QueryWrapper<User>().eq("username", loginDto.getUserName()));
        //如果不存在返回用户名不存在
        if(ObjectUtil.isEmpty(login)){
            throw new ZhentaoException(ResultCodeEnum.LOGIN_ERROR);
        }
        //如果存在把这个用户的密码取出来
        String password1 = login.getPassword();
        //然后截取加密后的密码
        String substring = password1.substring(4, password1.length());
        System.out.println("============>"+substring);
        //把用户输入的密码加密解析进行对比
        String s = DigestUtils.md5DigestAsHex(password.getBytes());
        System.out.println("=============>s="+s);
        //如果错误
        if(!substring.equals(s)){
            throw new ZhentaoException(ResultCodeEnum.LOGIN_ERROR);
        }
        //正确以后生成token保存到redis
        String token = IdUtil.simpleUUID().replace("-", "");
        //token有效时长30分钟
        redisTemplate.opsForValue().set("user:login:" + token, JSON.toJSONString(login), 30, TimeUnit.MINUTES);
        LoginVo loginVo = new LoginVo();
        //设置token
        loginVo.setToken(token);
        //设置refresh_token
        loginVo.setRefresh_token("");
        //返回
        return loginVo;
    }

    @Override
    public UserInfoVo getUserInfo(String token) {
//        数据校验
        if (StrUtil.isBlank(token)) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        String userInfo = redisTemplate.opsForValue().get("user:login:" + token);
        //数据校验
        if (StrUtil.isBlank(userInfo)) {
            throw new ZhentaoException(ResultCodeEnum.LOGIN_ERROR);
        }
        //把json字符串转换成对象
        User User = JSON.parseObject(userInfo,User.class);
        System.out.println("获取用户的id"+User.getId());
        //实例化对象
        UserInfoVo userInfoVo = new UserInfoVo();
        //拷贝
        BeanUtils.copyProperties(User, userInfoVo);
        System.out.println("获取到的"+userInfoVo.getId());
        //返回
        return userInfoVo;
    }

    @Override
    public ValidateCodeVo getValidateCode() {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 5);
        //获取验证码的值
        String code = captcha.getCode();
        //用来生成图片的base64字符串
        String imageBase64 = captcha.getImageBase64();
        //把验证码保存到redis 中
        String key = IdUtil.simpleUUID().replace("-", "");
        redisTemplate.opsForValue().set("validateCode:" + key, code, 1, TimeUnit.MINUTES);
        ValidateCodeVo validateCodeVo = new ValidateCodeVo();
        validateCodeVo.setCodeKey(key);
        validateCodeVo.setCodeValue("data:image/png;base64," + imageBase64);
        //响应结果
        return validateCodeVo;
    }

    /**
     * 根据redis中用户的key 删除
     * @param token
     */
    @Override
    public void logout(String token) {
        if (StrUtil.isBlank(token)) {
            throw new RuntimeException("参数不能为空");
        }
        //数据校验
        redisTemplate.delete("user:login:" + token);
    }

//    @Autowired
//    private IdWorker idWorker;
    @Override
    public boolean register(UserDto userdto) {
        System.out.println(userdto.getUsername());
        System.out.println(userdto.getPhone());
        System.out.println(userdto.getPassword());
        if (ObjectUtil.isEmpty(userdto)) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
//        if (ObjectUtil.isEmpty(userMapper.selectByUsername(userdto.getUsername()))) {
//            throw new ZhentaoException(ResultCodeEnum.USER_NAME_IS_EXISTS);
//        }
//        if (ObjectUtil.isEmpty(userMapper.selectByPhone(userdto.getPhone()))) {
//            throw new ZhentaoException(ResultCodeEnum.PHONE_IS_EXISTS);
//        }
        //实例化对象
        User user = new User();
        //生成雪花id
        IdWorker worker = new IdWorker();
        user.setId(worker.nextId());
        //设置用户名
        user.setUsername(userdto.getUsername());
        //设置密码+研值
        String substring = UUID.randomUUID().toString().substring(0, 4);
        String s = DigestUtils.md5DigestAsHex(userdto.getPassword().getBytes());
        String password = substring + s;
        user.setPassword(password);
        user.setPhone(userdto.getPhone());
        this.userMapper.insert(user);
        return true;
    }

    @Override
    public User updatePassword(String token,UserVo userVo) {
        //通过token从redis中获取用户信息
        User user = JSON.parseObject(redisTemplate.opsForValue().get("user:login:" + token), User.class);
        //用户输入的原密码
        String password = userVo.getPassword();
        //将用户输入的原密码进行加密
        String s = DigestUtils.md5DigestAsHex(password.getBytes());
        //在取用户的原密码
        String substring = user.getPassword().substring(4, user.getPassword().length());
        //进行比较
        if (!substring.equals(s)) {
            throw new ZhentaoException(ResultCodeEnum.PASSWORD_ERROR);
        }
        //将用户输入的新密码进行加密
        String s1 = DigestUtils.md5DigestAsHex(userVo.getNewPassword().getBytes());
        //取随机值
        String substring1 = UUID.randomUUID().toString().substring(0, 4);
        //将加密后的密码拼接
        String newPassword =  substring1 + s1;
        //设置新密码
        user.setPassword(newPassword);
        //更新数据库
        userMapper.updateById(user);
        return null;
    }

    @Override
    public User updateUserinfo(String token, UserByInfo userByInfo) {
        if (StrUtil.isBlank(token)) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        return null;
    }
    @Value("${sms.accessKey}")
    private String accessKey;

    @Value("${sms.secretKey}")
    private String secretKey;

    @Value("${sms.signName}")
    private String signName;

    @Value("${sms.templateCode}")
    private String templateCode;
    @Override
    public boolean send(String phone, Map<String, Object> map) {
        DefaultProfile profile = DefaultProfile.getProfile("default", this.accessKey,this.secretKey);
        //发起 客户端
        IAcsClient client = new DefaultAcsClient(profile);
        //设置短信发送的信息 签名 手机号码 验证码
        CommonRequest request=new CommonRequest();
        //设置请求方式
        request.setSysMethod(MethodType.POST);
        //设置阿里云节点
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        //设置手机号码 设置成自己的
        request.putQueryParameter("PhoneNumbers",phone);
        //设置签名
        request.putQueryParameter("SignName",this.signName);
        //设置模板
        request.putQueryParameter("TemplateCode",this.templateCode);
        request.putQueryParameter("TemplateParam", JSONObject.toJSONString(map));

        try {
            CommonResponse response=client.getCommonResponse(request);
            System.out.println(response);
            return response.getHttpResponse().isSuccess();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
        return false;
    }

    @Override
    public LoginVo phoneLogin(LoginDto loginDto) {
        //根据手机号和验证码进行判断
        if (StrUtil.isBlank(loginDto.getPhone()) || StrUtil.isBlank(loginDto.getCode())) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        String phone = loginDto.getPhone();
        String code = loginDto.getCode();

        if (StrUtil.isBlank(redisTemplate.opsForValue().get(phone + "_" + code))){
            throw new ZhentaoException(ResultCodeEnum.CAPTCHA_ERROR);
        }
        //查询用户
        User user = userMapper.selectByPhone(phone);
        if (ObjectUtil.isEmpty(user)) {
            throw new ZhentaoException(ResultCodeEnum.LOGIN_ERROR);
        }
        //正确以后生成token保存到redis
        String token = IdUtil.simpleUUID().replace("-", "");
        redisTemplate.opsForValue().set("user:login:" + token, JSON.toJSONString(user), 30, TimeUnit.MINUTES);
        LoginVo loginVo = new LoginVo();
        //设置token
        loginVo.setToken(token);
        //设置refresh_token
        loginVo.setRefresh_token("");
        //返回
        return loginVo;
    }


    @Override
    public boolean updateUnLoan(String token, UserInfoVo userByInfo) {
        //获取用户信息
        if(StrUtil.isEmpty(token)){
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        if(userByInfo==null){
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        System.out.println("s===>"+userByInfo.getS());
        System.out.println("传过来id"+userByInfo.getId());
        User user = JSON.parseObject(redisTemplate.opsForValue().get("user:login:" + token), User.class);
        System.out.println("====>user"+user);
        if (ObjectUtil.isEmpty(user)){
            throw new ZhentaoException(ResultCodeEnum.LOGIN_AUTH);
        }
        if (!user.getId().equals(userByInfo.getId())){
            throw new ZhentaoException(ResultCodeEnum.LOGIN_AUTH);
        }
        System.out.println("编译id"+user.getId());
        //0是➕ 1是➖
        if(userByInfo.getS()==0){
            //获取要加的钱
            BigDecimal amount = userByInfo.getAmount();
            BigDecimal un = user.getUn();
            BigDecimal add = un.add(amount);
            amount= add;
            this.userMapper.updateByUn(user.getId(),amount);
        }
        if(userByInfo.getS()==1){
            BigDecimal amount = userByInfo.getAmount();
            BigDecimal un = user.getUn();
            //判断账户余额是否够用
            if(un.intValue()<amount.intValue()){
                throw new ZhentaoException(ResultCodeEnum.STOCK_LESS);
            }
            this.userMapper.updateByUns(user.getId(),amount);
        }
        return true;
    }

    @Override
    public User getUserByName(String userName) {
        if (StrUtil.isBlank(userName)) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        User user = this.userMapper.selectByUsername(userName);
        if (user==null){
            throw new ZhentaoException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        return user;
    }

    @Override
    public User forgetPassword(UserDto userDto) {
        String username = userDto.getUsername();
        String password = userDto.getPassword();
        String phone = userDto.getPhone();
        System.out.println("username===>"+username);
        System.out.println("password===>"+password);
        System.out.println("phone===>"+phone);
        User user = this.userMapper.selectByUsername(username);
        if (user==null){
            throw new ZhentaoException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        if (user.getPhone().equals(phone)){
            //设置密码+研值
            String substring = UUID.randomUUID().toString().substring(0, 4);
            String s = DigestUtils.md5DigestAsHex(userDto.getPassword().getBytes());
            String passwords = substring + s;
            user.setPassword(passwords);
            this.userMapper.updateById(user);
        }
        return user;
    }

    @Override
    public User getUserByPhone(String phone) {
        User user = this.userMapper.selectByPhone(phone);
        if (user==null){
            throw new ZhentaoException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        return user;
    }

    @Override
    public UserInfoVo updateUnId(String token, UserInfoVo userInfoVo) {
        if (StrUtil.isBlank(token)){
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        String realname = userInfoVo.getRealname();
        String idcard = userInfoVo.getIdcard();
        Long id = userInfoVo.getId();
        User user=new User();
        user.setId(id);
        user.setRealname(realname);
        user.setIdcard(idcard);
        userMapper.updates(user.getRealname(),user.getIdcard(),user.getId());
        return userInfoVo;
    }

    @Override
    public UserInfoVo addMoney(String token, UserInfoVo userInfoVo) {
        if (StrUtil.isBlank(token)){
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        Long id = userInfoVo.getId();
        System.out.println(id);
        BigDecimal amount = userInfoVo.getAmount();
        System.out.println("amount===>"+amount);
        int s = userInfoVo.getS();
        System.out.println("s===>"+s);
        if (s==0){
            this.userMapper.updateByUn(id,amount);
        }else {
            this.userMapper.updateByUns(id,amount);
        }
        return userInfoVo;
    }

    @Override
    public UserInfoVo getMyunNum(String token, Long id) {
        if (StrUtil.isBlank(token)){
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        User user = this.userMapper.selectbyId(id);
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setUn(user.getUn());
        return userInfoVo;
    }

    @Override
    public Result banalceNumber(String banalce, String cardnumber) {
        System.out.println("充值");
        Result account = this.ztyhRecordingserviceOpen.account(banalce, cardnumber);
        return account;
    }
    @Override
    public Result nobanalceNumber(String banalce, String cardnumber) {
        System.out.println("提现");
        Result chong = this.ztyhRecordingserviceOpen.chong(banalce, cardnumber);
        return chong;
    }

    @Override
    public Result getUserJls(Long userId, String startTime, String endTime) {
        return this.ztyhCardOpen.findMyjls(userId, startTime, endTime);
    }

    @Override
    public User getPhoneUsersname(String realname, String phone) {
        User phoneUsersname = this.userMapper.getPhoneUsersname(realname, phone);
        if (phoneUsersname==null){
            throw new ZhentaoException(ResultCodeEnum.ACCOUNT_STOP);
        }
        return phoneUsersname;
    }

    @Override
    public int updateUnAmount(String phone, BigDecimal amount) {
        return this.userMapper.updateUnAmount(phone, amount);
    }


    @Override
    public boolean addCard(Long moneyOut, Long moneyIn, BigDecimal amount, Integer operatorType) {
        boolean b = this.ztyhCardOpen.addRecording(moneyOut, moneyIn, amount, operatorType);
        return b;
    }

    @Override
    public UserInfoVo NoaddMoney(String token, UserInfoVo userInfoVo) {
        if (StrUtil.isBlank(token)){
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }
        Long id = userInfoVo.getId();
        System.out.println(id);
        BigDecimal amount = userInfoVo.getAmount();
        System.out.println("amount===>"+amount);
        int s = userInfoVo.getS();
        System.out.println("s===>"+s);
        if (s==0){
            this.userMapper.updateByUne(id,amount);
        }
        return userInfoVo;
    }




}




